from odoo import api, fields, models
import logging
from odoo.exceptions import ValidationError
import os
from dateutil.relativedelta import relativedelta
import base64

class SendMessage(models.Model):
    _name = 'send.message'
    _description = '发送工作通知'

    name = fields.Char('消息名称')
    type = fields.Selection([('text', '发送文本消息'),
                             ('image', '发送图片消息'),
                             ('voice', '发送语音消息(wu)'),
                             ('link', '发送链接信息'),
                             ('file', '发送文件消息'),
                             ('action_card', '发送卡片消息(wu)')], string='类型')
    msg_text = fields.Text(string='发送文本内容')
    send_all = fields.Selection([('yes', '是'), ('no', '否')], string='是否发送所有人')
    employee_ids = fields.Many2many('hr.employee', string='接收人')
    department_ids = fields.Many2many('hr.department', string='接收部门')
    media_id = fields.Many2one('send.media', string='图片/媒体文件')
    active = fields.Boolean(default=False, string="启用")
    dingtalk_config_id = fields.Many2one('dingtalk.config', string='工作通知应用')
    link_url = fields.Char(string='链接地址')
    line_title = fields.Char(string='消息标题')
    link_text = fields.Char(string='消息描述')

    def do_active(self):
        if self.active:
            self.active = False
        else:
            self.active = True

    def fmt_msg(self):
        if self.type == 'text':
            msg = {
                "msgtype": "text",
                "text": {
                    "content": self.msg_text + str(fields.Datetime.now() + relativedelta(hours=8))
                }
            }
        elif self.type in ['image', 'file']:
            media_id = self.media_id.dingtalk_media_id
            msg = {
                "msgtype": "image",
                "image": {
                    "media_id": media_id
                }
            }
        elif self.type == 'link':
            media_id = self.media_id.dingtalk_media_id
            msg = {
                "msgtype": "link",
                "link": {
                    "messageUrl": self.link_url,
                    "picUrl": media_id,
                    "title": self.line_title,
                    "text": self.link_text
                }
            }
        else:
            msg = None
        return msg

    def send_msg(self, msg=None):
        if not self.active:
            raise ValidationError('请先激活该消息内容后再次发送通知')
        if not msg:
            msg = self.fmt_msg()
        if not msg:
            raise ValidationError('请配置消息体后进行发送')
        msg_env = self.env['dingtalk.message']
        res = msg_env.asyncsend(msg=msg,
                                agent_id=self.dingtalk_config_id.agent_id,
                                userid_list=','.join([e.dingtalk_id for e in self.employee_ids if e.dingtalk_id]),
                                dept_id_list=','.join([d.dingtalk_id for d in self.department_ids if d.dingtalk_id]),
                                to_all_user=True if self.send_all == 'yes' else False)
        if res['errmsg'] == 'ok':
            self.env['send.log'].create({'message_id': self.id, 'content': msg, 'task_id': res['task_id']})
            return True
        else:
            raise ValidationError(res['errmsg'])


class SendMedia(models.Model):
    _name = 'send.media'
    _description = '上传媒体文件'

    name = fields.Char(string='名称')
    attachment_ids = fields.Many2many('ir.attachment', string='图片/媒体文件')
    dingtalk_media_id = fields.Char(string='资源id')
    file_dir = fields.Char(string="附件路径", compute="copy_file", store=True)
    file_name = fields.Char(string='文件名称', compute="copy_file", store=True)

    # 将上传的文件保存到本地
    @api.depends('attachment_ids')
    def copy_file(self):
        # 如果上传文件对象集合有内容
        if self.attachment_ids:
            # 循环文件对象集合
            for d in self.attachment_ids:
                # 转换格式
                content_base64 = base64.b64decode(d.datas)
                dir = os.getcwd()
                # 写入文件
                with open(dir + '/upload_dir/' + d.name, 'wb') as f:
                    f.write(content_base64)
                # 保存附件路径
                for i in self:
                    i.file_dir = dir + '/upload_dir/' + d.name
                    i.file_name = d.name

    @api.constrains('attachment_ids')
    def check_count(self):
        if len(self.attachment_ids) > 1:
            raise ValidationError('媒体资源只能上传一个')

    def upload(self):
        msg_env = self.env['dingtalk.message']
        msg_env.upload_media('image', self.file_name, self.file_dir)




class SendLog(models.Model):
    _name = 'send.log'
    _description = '发送消息日志'

    message_id = fields.Many2one('send.message', string='工作通知')
    content = fields.Text(string='发送内容')
    task_id = fields.Char(string='异步发送任务ID')
